import React, { useRef, useEffect } from 'react'
import * as THREE from 'three'
import Stats from 'three/examples/jsm/libs/stats.module'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader'
import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader'
import { CSS3DObject  } from 'three/examples/jsm/renderers/CSS3DRenderer'
import THREEProject from '../utils/index'
const opt = {
  width: window.innerWidth - 180,
  height: window.innerHeight
}
const perspectiveCameraOpt = [75, opt.width/opt.height, 0.1, 1000]
const loader = new GLTFLoader()

const Points = () => {
  // const COUNT = 1000
  const can = useRef(null)
  const scene = new THREE.Scene()
  const light = new THREE.AmbientLight(0xffffff)
  const renderer = new THREE.WebGLRenderer()
  const axes = new THREE.AxesHelper(50)
  renderer.setSize(opt.width, opt.height)
  // renderer.setClearColor(0xffffff)
  
  const camera = new THREE.PerspectiveCamera(...perspectiveCameraOpt)
  console.log(camera)
  camera.position.set(20, 40, 40)
  let controls = null

  const init = () => {
    const stats = new Stats()
    
    const box = drawBox()
    
    camera.target = scene
    console.log(scene)
    // scene.add(box)
    scene.add(light)
    scene.add(axes)
    scene.add(drawPoints())
    if(!can.current.children.length) {
      can.current.appendChild(renderer.domElement)
      can.current.appendChild(stats.dom)
    }
    controls = new OrbitControls(camera, renderer.domElement)
    // scene.add(orbit)
    animate()
  }

  const render = () => {
    controls.update()
    renderer.render(scene, camera)
  }

  const animate =  () => {
    render()
    requestAnimationFrame(animate)
  }

  const drawPoints = () => {
    const particlesCount = 1000
    const r = 800
    const particlesData = []
    const particles = new THREE.BufferGeometry()
    const particlePositions = new Float32Array(particlesCount * 3)
    const pMaterial = new THREE.PointsMaterial( {
      color: 0xFFFFFF,
      size: 3,
      blending: THREE.AdditiveBlending,
      transparent: true,
      sizeAttenuation: false
    } );
    for(let i = 0; i > particlesCount; i++) {
      const x = Math.random() * r - r / 2
      const y = Math.random() * r - r / 2
      const z = Math.random() * r - r / 2
      particlePositions[i * 3] = x
      particlePositions[i * 3 + 1] = y
      particlePositions[i * 3 + 2] = z
      particlesData.push({
        velocity: new THREE.Vector3(-1 + Math.random() * 2, -1 + Math.random() * 2, -1 + Math.random() * 2),
        numConnections: 0
      })
    }
    particles.setDrawRange( 0, particlesCount )
    particles.setAttribute( 'position', new THREE.BufferAttribute( particlePositions, 3 ).setUsage( THREE.DynamicDrawUsage ) );
    const pointCloud = new THREE.Points( particles, pMaterial )
    return pointCloud
  }

  const drawBox = () => {
    const boxGeometry = new THREE.BoxGeometry(20, 20, 20)
    const boxMaterial = new THREE.MeshBasicMaterial({
      color: 0x000077,
      wireframe: true
    })
    const box = new THREE.Mesh(boxGeometry, boxMaterial)
    box.position.set(0.1,0.1,0.1)
    return box
  }

  useEffect(init, [])

  return (
    <div ref={can}>
    </div>
  )
}



const Plane = () => {
  const can = useRef(null)
  const scene = new THREE.Scene()
  const light = new THREE.AmbientLight(0xffffff)
  const renderer = new THREE.WebGLRenderer()
  renderer.setSize(opt.width, opt.height)
  // renderer.setClearColor(0xffffff)
  let controls = null
  const camera = new THREE.PerspectiveCamera(...perspectiveCameraOpt)
  camera.position.set(0.8, 0.8, 1.2)
  const init = () => {
    camera.target = scene
    scene.add(light)
    if(!can.current.children.length) {
      can.current.appendChild(renderer.domElement)
    }
    controls = new OrbitControls(camera, renderer.domElement)
    controls.autoRotate = true
    // scene.add(orbit)
    loadModel()
    animate()
  }
  const loadModel = () => {
    loader.load('/assets/七星河泵.glb', (glb) => {
      const glbScene = glb.scene
      glbScene.scale = new THREE.Vector3(5,5,5)
      const mesh = glbScene.getObjectByName("微信图片_20210425104744")
      
      const texture = new THREE.TextureLoader().load('/assets/地形/20210426152552.png')
      console.log('texture', texture)
      texture.wrapS = texture.wrapT = THREE.RepeatWrapping
      texture.rotation = Math.PI 
      mesh.material = new THREE.MeshStandardMaterial({
        map:texture,
        side: THREE.DoubleSide
      })
      scene.add(glbScene)
    })
  }
  const render = () => {
    controls.update()
    renderer.render(scene, camera)
  }
  const animate =  () => {
    render()
    requestAnimationFrame(animate)
  }
  useEffect(init, [])
  return (
    <div ref={can}></div>
  )
}

const CSSObject = () => {
  const can = useRef(null)
  const pro = new THREEProject()
  const { thr, renderer, scene, axes, camera, controls } = pro
  
  const init = () => {
    const t = createObject()
    const light = new thr.AmbientLight(0xffffff)
    scene.add(light)
    scene.add(t)
    scene.add(axes)
    if(!can.current.children.length) {
      can.current.appendChild(renderer.domElement)
    }
    animate()
  }
  const createObject = (params = {}, pos = new THREE.Vector3(-50, 0, 0), rot = new THREE.Euler(0, -90 * THREE.MathUtils.DEG2RAD, 0)) => {
    const material = new THREE.MeshBasicMaterial( { color: 0x000000, wireframe: true, wireframeLinewidth: 1, side: THREE.DoubleSide } );
    const options = {
      width: '100px',
      height: '100px',
      opacity: 0.75,
      backgroundColor: '#007777',
      ...params
    }
    const element = document.createElement('div')
    element.style = {...options}
    
    const object = new CSS3DObject( element )
    object.position.copy( pos )
    object.position.copy( rot )

    const geometry = new THREE.PlaneGeometry(parseInt(options.width), parseInt(options.height))
    const mesh = new THREE.Mesh( geometry, material )
    mesh.position.copy( object.position )
    mesh.rotation.copy( object.rotation )

    return mesh
  }
  const render = () => {
    controls.update()
    renderer.render(scene, camera)
  }
  const animate = () => {
    requestAnimationFrame(animate)
    render()
  }
  useEffect(init, [])
  return (
    <div ref={can}></div>
  )
}

export {
  Points,
  Plane,
  CSSObject
}